package com.moorecat.http;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.json.JSONException;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;

import com.moorecat.config.Const;
import com.moorecat.domain.ResBean;
import com.moorecat.enums.ResultStatusEnum;
import com.moorecat.exception.SVException;
import com.moorecat.utils.JsonUtils;
import com.moorecat.utils.ResponseResultBean;

/** 
 * 类说明 
 * @author  pengfei.xu 
 * @version V1.0  创建时间：2011-4-28 下午05:31:29 
 */
public class HttpConnectionImpl implements HttpConnection {
	
	public static final String TAG = "HttpConnectionImpl";
	
	@Override
	public ResBean login(String url,Map<String,String> headers) {
		HttpClient hc = createHttpClient(10*1000);
		ResBean resBean = new ResBean();
		try {
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = hc.execute(httpGet);
			resBean.setStatus(response.getStatusLine().getStatusCode());
			Header[] responseHeaders = response.getAllHeaders();
			Map<String,String> map = new HashMap<String,String>();
			for(Header header:responseHeaders){
				map.put(header.getName(), header.getValue());
			}
			resBean.setHeaders(map);
			resBean.setData(getString(response));
		} catch (Exception e) {

		} finally {
			hc.getConnectionManager().shutdown();
		}
		return resBean;
	}
	
	@Override
	public ResBean getStream(String url, Map<String, String> headers) {
		return getStream(url, headers, 10 * 1000);
	}

	@Override
	public ResBean getStream(String url, Map<String, String> headers,
			int timeout) {
		Log.i(TAG,"[HTTP][GET]["+url+"]");
		HttpClient hc = createHttpClient(timeout);
		ResBean resBean = new ResBean();
		try {
			HttpGet httpGet = new HttpGet(url);
			addHeaders(httpGet, headers);
			HttpResponse response = hc.execute(httpGet);
			resBean.setStatus(response.getStatusLine().getStatusCode());
			resBean.setData(getString(response));
		} catch (Exception e) {
			
		} finally {
			hc.getConnectionManager().shutdown();
		}
		return resBean;
	}

	@Override
	public ResBean postStream(String url, Map<String, String> headers,
			Map<String, String> params) {
		return postStream(url, headers, params, 10 * 1000);
	}

	@Override
	public ResBean postStream(String url, Map<String, String> headers,
			Map<String, String> params, int timeout) {

		HttpClient hc = createHttpClient(timeout);
		ResBean resBean = new ResBean();
		try {
			HttpPost httpPost = new HttpPost(url);
			addHeaders(httpPost, headers);
			List<NameValuePair> formparams = new ArrayList<NameValuePair>();
			for (Map.Entry<String, String> param : params.entrySet()) {
				formparams.add(new BasicNameValuePair(param.getKey(), param.getValue()));
			}
			UrlEncodedFormEntity entity = new UrlEncodedFormEntity(formparams, "UTF-8");
			httpPost.setEntity(entity);
			HttpResponse response = hc.execute(httpPost);
			resBean.setData(getString(response));
			resBean.setStatus(response.getStatusLine().getStatusCode());
		} catch (Exception e) {

		} finally {
			hc.getConnectionManager().shutdown();
		}
		return resBean;
	}

	@Override
	public Bitmap downloadBitmap(String queryUrl) {
		return downloadBitmap(queryUrl, 30 * 3000);
	}

	@Override
	public Bitmap downloadBitmap(String url, int timeout) {
		HttpClient hc = createHttpClient(timeout);
		Bitmap bitmap = null;
		try {
			HttpGet httpGet = new HttpGet(url);
			HttpResponse response = hc.execute(httpGet);
			int status = response.getStatusLine().getStatusCode();
			if ( status == Const.RESPONSE_OK) {
				byte[] images = getbytes(response);
				bitmap = BitmapFactory.decodeByteArray(images, 0, images.length);
			}
		} catch (Exception e) {
			
		} finally {
			hc.getConnectionManager().shutdown();
		}
		return bitmap;
	}

	private HttpClient createHttpClient(int timeout) {
		HttpClient hc = new DefaultHttpClient();
		HttpParams params = hc.getParams();
		params.setIntParameter("http.socket.timeout", 1000*40);
		return hc;
	}

	private void addHeaders(HttpRequestBase httpRequest,
			Map<String, String> headers) {
		if (headers != null) {
			for (Map.Entry<String, String> entry : headers.entrySet()) {
				httpRequest.addHeader(entry.getKey(), entry.getValue());
			}
		}
	}

	/**
	 * HttpResponse转换成String输出
	 * 
	 * @param response
	 * @return
	 */
	private String getString(HttpResponse response) {
		String result = null;
		byte[] bytes = getbytes(response);
		if (bytes != null) {
			try {
				result = new String(bytes, "UTF-8");
			} catch (UnsupportedEncodingException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return result;
	}

	/**
	 * HttpResponse转换成byte[]输出
	 * 
	 * @param response
	 * @return
	 */
	private byte[] getbytes(HttpResponse response) {
		byte[] bytes = null;
		HttpEntity entity = response.getEntity();
		try {
			bytes = EntityUtils.toByteArray(entity);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return bytes;
	}
	
	public ResponseResultBean getJSONBean(String url, Map<String, String> headers) throws SVException{
		ResponseResultBean bean = null;
		ResBean rb = getStream(url, headers);
		if(rb != null && rb.getStatus() == HttpStatus.SC_OK){
			try {
				Log.d(TAG, rb.getData());
				bean = JsonUtils.toResponseResultBean(rb.getData());
				if(bean != null){
					if(bean.getStatus() != ResultStatusEnum.SUCCESS.getCode()){
						throw new SVException(bean.getStatus(), bean.getMsg());
					}
				}else{
					throw new SVException(ResultStatusEnum.FAILED.getCode(), "结果解析不符合要求");
				}
			} catch (JSONException e) {
				String errMsg = "JSON解析出现异常";
				Log.e(TAG, errMsg, e);
				throw new SVException(ResultStatusEnum.FAILED.getCode(), errMsg);
			}
		}else{
			String errMsg = "从远程获取服务失败，请检查网络，URL,服务是否可用";
			Log.e(TAG, errMsg);
			throw new SVException(ResultStatusEnum.FAILED.getCode(), errMsg);
		}
		return bean;
	}
}
